Vabastage React Hookide võimekus, meisterdades kohandatud hooke taaskasutatava loogika, puhta koodi ja skaleeruvate globaalsete rakenduste jaoks.
React Hookide Mustrid: Kohandatud Hookide Arendamise Meisterlikkus Globaalsetele Rakendustele
Pidevalt arenevas veebiarenduse maastikul on React järjepidevalt püsinud nurgakivina dünaamiliste ja interaktiivsete kasutajaliideste ehitamisel. React Hookide kasutuselevõtuga said arendajad revolutsioonilise viisi funktsionaalsete komponentide oleku ja kõrvalmõjude haldamiseks, asendades paljudes olukordades tõhusalt vajaduse klassikomponentide järele. See paradigma muutus tõi kaasa puhtama, lühema ja paremini taaskasutatava koodi.
Hookide üks võimsamaid omadusi on võime luua kohandatud Hooke. Kohandatud Hookid on JavaScripti funktsioonid, mille nimed algavad sõnaga "use" ja mis võivad kutsuda teisi Hooke. Need võimaldavad teil eraldada komponendi loogikat taaskasutatavatesse funktsioonidesse, edendades paremat organiseeritust, testitavust ja skaleeruvust – mis on olulised aspektid mitmekesist globaalset publikut teenindavate rakenduste jaoks.
See põhjalik juhend süveneb React Hookide mustritesse, keskendudes kohandatud Hookide arendamisele. Uurime, miks need on asendamatud, kuidas neid tõhusalt ehitada, levinud mustreid, edasijõudnud tehnikaid ja olulisi kaalutlusi vastupidavate, suure jõudlusega rakenduste loomisel, mis on mõeldud kasutajatele üle kogu maailma.
React Hookide Põhitõdede Mõistmine
Enne kohandatud Hookide juurde sukeldumist on oluline mõista sisseehitatud React Hookide põhitõdesid. Need pakuvad vajalikke primitiive olekuhalduseks ja kõrvalmõjudeks funktsionaalsetes komponentides.
Hookide Põhiprintsiibid
useState: Haldab komponendi lokaalset olekut. See tagastab olekupõhise väärtuse ja funktsiooni selle uuendamiseks.useEffect: Teostab kõrvalmõjusid funktsionaalsetes komponentides, nagu andmete pärimine, tellimused või DOM-i käsitsi muutmine. See käivitub pärast iga renderdamist, kuid selle käitumist saab kontrollida sõltuvuste massiiviga.useContext: Tarbib väärtusi Reacti kontekstist, võimaldades teil andmeid edastada läbi komponendipuu ilma prop'ide edasiandmiseta (prop drilling).useRef: Tagastab muudetava ref-objekti, mille.currentomadus on initsialiseeritud antud argumendiga. Kasulik DOM-i elementidele juurdepääsuks või väärtuste säilitamiseks renderduste vahel ilma uusi renderdusi põhjustamata.useCallback: Tagastab tagasikutsefunktsiooni memoiseeritud versiooni, mis muutub ainult siis, kui mõni sõltuvus on muutunud. Kasulik alamkomponentide optimeerimiseks, mis tuginevad viidete võrdsusele, et vältida tarbetuid uuesti renderdusi.useMemo: Tagastab memoiseeritud väärtuse, mis arvutatakse uuesti ainult siis, kui mõni sõltuvus on muutunud. Kasulik kulukate arvutuste jaoks.useReducer: AlternatiivuseState'ile keerukama olekuloogika jaoks, sarnaselt Reduxile, kus olekuüleminekud hõlmavad mitut alamväärtust või järgmine olek sõltub eelmisest.
Hookide Reeglid: Pidage meeles, et Hookide jaoks on kaks olulist reeglit, mis kehtivad ka kohandatud Hookidele:
- Kutsu Hooke ainult tipptasemel: Ära kutsu Hooke tsüklite, tingimuste või pesastatud funktsioonide sees.
- Kutsu Hooke ainult Reacti funktsioonidest: Kutsu neid Reacti funktsionaalsetest komponentidest või teistest kohandatud Hookidest.
Kohandatud Hookide Võimsus: Miks Neid Arendada?
Kohandatud Hookid ei ole lihtsalt suvaline funktsioon; need lahendavad olulisi väljakutseid kaasaegses Reacti arenduses, pakkudes märkimisväärseid eeliseid igas suuruses projektidele, eriti neile, millel on globaalsed nõuded järjepidevusele ja hooldatavusele.
Taaskasutatava Loogika Kapseldamine
Kohandatud Hookide peamine motivatsioon on koodi taaskasutamine. Enne Hooke kasutati loogika jagamiseks mustreid nagu Higher-Order Components (HOCs) ja Render Props, kuid need viisid sageli "wrapper hell"-ini, keeruliste prop'ide nimetamiseni ja suurenenud komponendipuu sügavuseni. Kohandatud Hookid võimaldavad teil eraldada ja taaskasutada olekupõhist loogikat ilma uusi komponente puusse lisamata.
Mõelge loogikale andmete pärimiseks, vormi sisendite haldamiseks või brauseri sündmuste käsitlemiseks. Selle asemel, et seda koodi mitmes komponendis dubleerida, saate selle kapseldada kohandatud Hooki ning lihtsalt importida ja kasutada seda seal, kus vaja. See vähendab korduvkoodi ja tagab järjepidevuse kogu rakenduses, mis on ülioluline, kui erinevad meeskonnad või arendajad üle maailma panustavad samasse koodibaasi.
Vastutusalade Eraldamine
Kohandatud Hookid soodustavad puhtamat eraldamist teie esitusloogika (kuidas kasutajaliides välja näeb) ja äriloogika (kuidas andmeid käsitletakse) vahel. Komponent saab keskenduda ainult renderdamisele, samal ajal kui kohandatud Hook saab tegeleda andmete pärimise, valideerimise, tellimuste või mis tahes muu mittevisuaalse loogika keerukusega. See muudab komponendid väiksemaks, loetavamaks ning lihtsamini mõistetavaks, silutavaks ja muudetavaks.
Testitavuse Parandamine
Kuna kohandatud Hookid kapseldavad spetsiifilisi loogikajuppe, muutuvad need lihtsamini eraldiseisvalt ühiktestitavaks. Saate testida Hooki käitumist, ilma et peaksite renderdama tervet Reacti komponenti või simuleerima kasutaja interaktsioone. Teegid nagu `@testing-library/react-hooks` pakuvad utiliite kohandatud Hookide iseseisvaks testimiseks, tagades, et teie põhiloogika toimib korrektselt, olenemata sellest, millise kasutajaliidesega see on ühendatud.
Parem Loetavus ja Hooldatavus
Abstrakteerides keerulise loogika kirjeldavate nimedega kohandatud Hookidesse, muutuvad teie komponendid palju loetavamaks. Komponent, mis kasutab useAuth(), useShoppingCart() või useGeolocation(), annab kohe edasi oma võimekuse, ilma et peaks süvenema implementatsiooni detailidesse. See selgus on hindamatu suurtes meeskondades, eriti kui erineva keelelise või haridusliku taustaga arendajad teevad koostööd ühise projekti kallal.
Kohandatud Hooki Anatoomia
Kohandatud Hooki loomine on lihtne, kui olete mõistnud selle põhilist struktuuri ja konventsioone.
Nimekonventsioon: Eesliide 'use'
Konventsiooni kohaselt peavad kõik kohandatud Hookid algama sõnaga "use" (nt useCounter, useInput, useDebounce). See nimekonventsioon annab Reacti linterile (ja teistele arendajatele) märku, et funktsioon järgib Hookide Reegleid ja võib potentsiaalselt kutsuda sisemiselt teisi Hooke. React ise seda rangelt ei jõusta, kuid see on kriitiline konventsioon tööriistade ühilduvuse ja koodi selguse jaoks.
Hookide Reeglid Kohandatud Hookidele
Nagu sisseehitatud Hookid, peavad ka kohandatud Hookid järgima Hookide Reegleid. See tähendab, et saate teisi Hooke (useState, useEffect jne) kutsuda ainult oma kohandatud Hooki funktsiooni tipptasemel. Te ei tohi neid kutsuda tingimuslausete, tsüklite või pesastatud funktsioonide sees oma kohandatud Hookis.
Argumentide Edastamine ja Väärtuste Tagastamine
Kohandatud Hookid on tavalised JavaScripti funktsioonid, seega võivad nad vastu võtta argumente ja tagastada mis tahes väärtusi – olekut, funktsioone, objekte või massiive. See paindlikkus võimaldab teil muuta oma Hookid väga konfigureeritavaks ja paljastada täpselt seda, mida tarbiv komponent vajab.
Näide: Lihtne useCounter Hook
Loome põhilise useCounter Hooki, mis haldab suurendatavat ja vähendatavat numbrilist olekut.
import React, { useState, useCallback } from 'react';
/**
* Kohandatud hook numbrilise loenduri haldamiseks.
* @param {number} initialValue - Loenduri algväärtus. Vaikimisi 0.
* @returns {{ count: number, increment: () => void, decrement: () => void, reset: () => void }}
*/
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []); // Sõltuvusi pole, kuna setCount on stabiilne
const decrement = useCallback(() => {
setCount(prevCount => prevCount - 1);
}, []); // Sõltuvusi pole
const reset = useCallback(() => {
setCount(initialValue);
}, [initialValue]); // Sõltub initialValue'st
return {
count,
increment,
decrement,
reset
};
}
export default useCounter;
Ja siin on, kuidas seda komponendis kasutada:
import React from 'react';
import useCounter from './useCounter'; // Eeldades, et useCounter.js on samas kaustas
function CounterComponent() {
const { count, increment, decrement, reset } = useCounter(10);
return (
<div>
<h3>Praegune arv: {count}</h3>
<button onClick={increment}>Suurenda</button>
<button onClick={decrement}>Vähenda</button>
<button onClick={reset}>Lähtesta</button>
</div>
);
}
export default CounterComponent;
See lihtne näide demonstreerib kapseldamist, taaskasutatavust ja selget vastutusalade eraldamist. CounterComponent ei hooli sellest, kuidas loenduri loogika töötab; see lihtsalt kasutab useCounter poolt pakutavaid funktsioone ja olekut.
Levinud React Hookide Mustrid ja Praktilised Kohandatud Hookide Näited
Kohandatud Hookid on uskumatult mitmekülgsed ja neid saab rakendada paljudele levinud arendusstsenaariumidele. Uurime mõningaid levinumaid mustreid.
1. Andmete Pärimise Hookid (useFetch / useAPI)
Asünkroonse andmete pärimise, laadimisolekute ja veakäsitluse haldamine on korduv ülesanne. Kohandatud Hook saab selle keerukuse abstraheerida, muutes teie komponendid puhtamaks ja keskendunuks andmete renderdamisele, mitte nende pärimisele.
import React, { useState, useEffect, useCallback } from 'react';
/**
* Kohandatud hook andmete pärimiseks API-st.
* @param {string} url - URL, kust andmeid pärida.
* @param {object} options - Fetchi valikud (nt päised, meetod, keha).
* @returns {{ data: any, loading: boolean, error: Error | null, refetch: () => void }}
*/
function useFetch(url, options = {}) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const fetchData = useCallback(async () => {
setLoading(true);
setError(null);
try {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`HTTP viga! staatus: ${response.status}`);
}
const result = await response.json();
setData(result);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
}, [url, JSON.stringify(options)]); // Stringify options süvavõrdluseks
useEffect(() => {
fetchData();
}, [fetchData]);
return { data, loading, error, refetch: fetchData };
}
export default useFetch;
Kasutusnäide:
import React from 'react';
import useFetch from './useFetch';
function UserProfile({ userId }) {
const { data: user, loading, error } = useFetch(`https://api.example.com/users/${userId}`);
if (loading) return <p>Laen kasutajaprofiili...</p>;
if (error) return <p style={{ color: 'red' }}>Viga: {error.message}</p>;
if (!user) return <p>Kasutaja andmeid ei leitud.</p>;
return (
<div>
<h2>{user.name}</h2>
<p>Email: {user.email}</p>
<p>Asukoht: {user.location}</p>
<!-- Veel kasutaja detaile -->
</div>
);
}
export default UserProfile;
Globaalse rakenduse jaoks saab useFetch hooki edasi arendada, et käsitleda veateadete rahvusvahelistamist, erinevaid API lõpp-punkte vastavalt piirkonnale või isegi integreerida globaalse vahemälustrateegiaga.
2. Olekuhalduse Hookid (useLocalStorage, useToggle)
Lisaks lihtsale komponendi olekule saavad kohandatud Hookid hallata keerukamaid või püsivaid olekunõudeid.
useLocalStorage: Oleku Säilitamine Sessioonide Vahel
See Hook võimaldab teil salvestada ja hankida olekutüki brauseri localStorage'ist, muutes selle püsivaks isegi pärast seda, kui kasutaja oma brauseri sulgeb. See on ideaalne teema eelistuste, kasutajaseadete või kasutaja valiku meelespidamiseks mitmeastmelises vormis.
import React, { useState, useEffect } from 'react';
/**
* Kohandatud hook oleku säilitamiseks localStorage'is.
* @param {string} key - localStorage'i võti.
* @param {any} initialValue - Algväärtus, kui localStorage'ist andmeid ei leita.
* @returns {[any, (value: any) => void]}
*/
function useLocalStorage(key, initialValue) {
// Olek meie väärtuse salvestamiseks
// Edasta algse oleku funktsioon useState'ile, et loogika käivitataks ainult üks kord
const [storedValue, setStoredValue] = useState(() => {
try {
const item = typeof window !== 'undefined' ? window.localStorage.getItem(key) : null;
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(`Viga localStorage võtme "${key}" lugemisel:`, error);
return initialValue;
}
});
// useEffect localStorage'i uuendamiseks, kui olek muutub
useEffect(() => {
try {
if (typeof window !== 'undefined') {
window.localStorage.setItem(key, JSON.stringify(storedValue));
}
} catch (error) {
console.error(`Viga localStorage võtmesse "${key}" kirjutamisel:`, error);
}
}, [key, storedValue]);
return [storedValue, setStoredValue];
}
export default useLocalStorage;
Kasutusnäide (Teema Vahetaja):
import React from 'react';
import useLocalStorage from './useLocalStorage';
function ThemeSwitcher() {
const [isDarkMode, setIsDarkMode] = useLocalStorage('theme-preference', false);
const toggleTheme = () => {
setIsDarkMode(prevMode => !prevMode);
document.body.className = isDarkMode ? '' : 'dark-theme'; // Rakenda CSS klass
};
return (
<div>
<p>Praegune teema: {isDarkMode ? '<strong>Tume</strong>' : '<strong>Hele</strong>'}</p>
<button onClick={toggleTheme}>
Vaheta {isDarkMode ? 'heledale' : 'tumedale'} teemale
</button>
</div>
);
}
export default ThemeSwitcher;
useToggle / useBoolean: Lihtne Boolean Olek
Kompaktne hook boolean-oleku haldamiseks, mida kasutatakse sageli modaalakende, rippmenüüde või märkeruutude jaoks.
import { useState, useCallback } from 'react';
/**
* Kohandatud hook boolean-oleku haldamiseks.
* @param {boolean} initialValue - Algne boolean väärtus. Vaikimisi false.
* @returns {[boolean, () => void, (value: boolean) => void]}
*/
function useToggle(initialValue = false) {
const [value, setValue] = useState(initialValue);
const toggle = useCallback(() => {
setValue(prev => !prev);
}, []);
return [value, toggle, setValue];
}
export default useToggle;
Kasutusnäide:
import React from 'react';
import useToggle from './useToggle';
function ModalComponent() {
const [isOpen, toggleOpen] = useToggle(false);
return (
<div>
<button onClick={toggleOpen}>LĂĽlita modaalakent</button>
{isOpen && (
<div style={{
border: '1px solid black',
padding: '20px',
margin: '10px',
backgroundColor: 'lightblue'
}}>
<h3>See on modaalaken</h3>
<p>Sisu läheb siia.</p>
<button onClick={toggleOpen}>Sulge modaalaken</button>
</div>
)}
</div>
);
}
export default ModalComponent;
3. SĂĽndmuste Kuulaja / DOM Interaktsiooni Hookid (useEventListener, useOutsideClick)
Brauseri DOM-i või globaalsete sündmustega suhtlemine hõlmab sageli sündmuste kuulajate lisamist ja eemaldamist, mis nõuab korrektset puhastust. Kohandatud Hookid sobivad suurepäraselt selle mustri kapseldamiseks.
useEventListener: Lihtsustatud Sündmuste Käsitlemine
See hook abstraheerib sündmuste kuulajate lisamise ja eemaldamise protsessi, tagades puhastuse, kui komponent eemaldatakse või sõltuvused muutuvad.
import { useEffect, useRef } from 'react';
/**
* Kohandatud hook sĂĽndmuste kuulajate lisamiseks ja puhastamiseks.
* @param {string} eventName - SĂĽndmuse nimi (nt 'click', 'resize').
* @param {function} handler - Sündmuse käsitleja funktsioon.
* @param {EventTarget} element - DOM-element, millele kuulaja lisada. Vaikimisi window.
* @param {object} options - SĂĽndmuste kuulaja valikud (nt { capture: true }).
*/
function useEventListener(eventName, handler, element = window, options = {}) {
// Loo ref, mis salvestab käsitleja
const savedHandler = useRef();
// Uuenda ref.current väärtust, kui käsitleja muutub. See võimaldab alloleval efektil
// alati kasutada uusimat käsitlejat, ilma et oleks vaja sündmuste kuulajat uuesti lisada.
useEffect(() => {
savedHandler.current = handler;
}, [handler]);
useEffect(() => {
// Veendu, et element toetab addEventListener'it
const isSupported = element && element.addEventListener;
if (!isSupported) return;
// Loo sĂĽndmuste kuulaja, mis kutsub savedHandler.current'it
const eventListener = event => savedHandler.current(event);
// Lisa sĂĽndmuste kuulaja
element.addEventListener(eventName, eventListener, options);
// Puhasta eemaldamisel või sõltuvuste muutumisel
return () => {
element.removeEventListener(eventName, eventListener, options);
};
}, [eventName, element, options]); // Käivita uuesti, kui eventName või element muutub
}
export default useEventListener;
Kasutusnäide (Klahvivajutuste Tuvastamine):
import React, { useState } from 'react';
import useEventListener from './useEventListener';
function KeyPressDetector() {
const [key, setKey] = useState('Puudub');
const handleKeyPress = (event) => {
setKey(event.key);
};
useEventListener('keydown', handleKeyPress);
return (
<div>
<p>Vajuta suvalist klahvi, et näha selle nime:</p>
<strong>Viimati vajutatud klahv: {key}</strong>
</div>
);
}
export default KeyPressDetector;
4. Vormide Käsitlemise Hookid (useForm)
Vormid on peaaegu kõigi rakenduste keskmes. Kohandatud Hook saab sujuvamaks muuta sisendi oleku haldamist, valideerimist ja esitamise loogikat, muutes keerulised vormid hallatavaks.
import { useState, useCallback } from 'react';
/**
* Kohandatud hook vormi oleku haldamiseks ja sisendi muudatuste käsitlemiseks.
* @param {object} initialValues - Objekt vormiväljade algväärtustega.
* @param {object} validationRules - Objekt valideerimisfunktsioonidega iga välja jaoks.
* @returns {{ values: object, errors: object, handleChange: (e: React.ChangeEvent) => void, handleSubmit: (callback: (values: object) => void) => (e: React.FormEvent) => void, resetForm: () => void }}
*/
function useForm(initialValues, validationRules = {}) {
const [values, setValues] = useState(initialValues);
const [errors, setErrors] = useState({});
const handleChange = useCallback((event) => {
event.persist(); // Säilita sündmus, et seda asünkroonselt kasutada (vajadusel)
const { name, value, type, checked } = event.target;
setValues((prevValues) => ({
...prevValues,
[name]: type === 'checkbox' ? checked : value,
}));
// Eemalda välja viga kohe, kui seda muudetakse
if (errors[name]) {
setErrors((prevErrors) => {
const newErrors = { ...prevErrors };
delete newErrors[name];
return newErrors;
});
}
}, [errors]);
const validate = useCallback(() => {
const newErrors = {};
for (const fieldName in validationRules) {
if (validationRules.hasOwnProperty(fieldName)) {
const rule = validationRules[fieldName];
const value = values[fieldName];
if (rule && !rule(value)) {
newErrors[fieldName] = `Vigane ${fieldName}`;
// Reaalses rakenduses pakuksid spetsiifilisi veateateid reegli alusel
}
}
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
}, [values, validationRules]);
const handleSubmit = useCallback((callback) => (event) => {
event.preventDefault();
const isValid = validate();
if (isValid) {
callback(values);
}
}, [values, validate]);
const resetForm = useCallback(() => {
setValues(initialValues);
setErrors({});
}, [initialValues]);
return {
values,
errors,
handleChange,
handleSubmit,
resetForm,
};
}
export default useForm;
Kasutusnäide (Sisselogimisvorm):
import React from 'react';
import useForm from './useForm';
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
function LoginForm() {
const { values, errors, handleChange, handleSubmit } = useForm(
{ email: '', password: '' },
{
email: (value) => emailRegex.test(value) && value.length > 0,
password: (value) => value.length >= 6,
}
);
const submitLogin = (formData) => {
alert(`Esitatakse: E-post: ${formData.email}, Parool: ${formData.password}`);
// Reaalses rakenduses saada andmed API-le
};
return (
<form onSubmit={handleSubmit(submitLogin)}>
<h2>Logi sisse</h2>
<div>
<label htmlFor="email">E-post:</label>
<input
type="email"
id="email"
name="email"
value={values.email}
onChange={handleChange}
/>
{errors.email && <p style={{ color: 'red' }}>{errors.email}</p>}
</div>
<div>
<label htmlFor="password">Parool:</label>
<input
type="password"
id="password"
name="password"
value={values.password}
onChange={handleChange}
/>
{errors.password && <p style={{ color: 'red' }}>{errors.password}</p>}
</div>
<button type="submit">Logi sisse</button>
</form>
);
}
export default LoginForm;
Globaalsete rakenduste jaoks võiks seda `useForm` hooki laiendada, et lisada i18n valideerimissõnumitele, käsitleda erinevaid kuupäeva/numbri vorminguid vastavalt lokaadile või integreerida riigipõhiste aadressi valideerimisteenustega.
Edasijõudnud Kohandatud Hookide Tehnikad ja Parimad Praktikad
Kohandatud Hookide Komponeerimine
Üks kohandatud Hookide võimsamaid aspekte on nende komponeeritavus. Saate ehitada keerulisi Hooke, kombineerides lihtsamaid, sarnaselt sellele, kuidas ehitate keerulisi komponente väiksematest, lihtsamatest. See võimaldab väga modulaarset ja hooldatavat loogikat.
Näiteks keerukas useChat hook võib sisemiselt kasutada useWebSocket'i (kohandatud hook WebSocket-ühenduste jaoks) ja useScrollIntoView'd (kohandatud hook kerimiskäitumise haldamiseks).
Context API koos Kohandatud Hookidega Globaalse Oleku jaoks
Kuigi kohandatud Hookid on suurepärased lokaalse oleku ja loogika jaoks, saab neid kombineerida ka Reacti Context API-ga, et hallata globaalset olekut. See muster asendab paljude rakenduste jaoks tõhusalt lahendusi nagu Redux, eriti kui globaalne olek ei ole liiga keeruline ega nõua vahevara (middleware).
// AuthContext.js
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
const AuthContext = createContext(null);
// Kohandatud Hook autentimisloogika jaoks
export function useAuth() {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
// Simuleeri asĂĽnkroonset sisselogimisfunktsiooni
const login = useCallback(async (username, password) => {
setIsLoading(true);
return new Promise(resolve => {
setTimeout(() => {
if (username === 'test' && password === 'password') {
const userData = { id: '123', name: 'Globaalne Kasutaja' };
setUser(userData);
localStorage.setItem('user', JSON.stringify(userData));
resolve(true);
} else {
resolve(false);
}
setIsLoading(false);
}, 1000);
});
}, []);
// Simuleeri asünkroonset väljalogimisfunktsiooni
const logout = useCallback(() => {
setUser(null);
localStorage.removeItem('user');
}, []);
// Lae kasutaja localStorage'ist komponendi laadimisel
useEffect(() => {
const storedUser = localStorage.getItem('user');
if (storedUser) {
try {
setUser(JSON.parse(storedUser));
} catch (e) {
console.error('Kasutaja localStorage\'ist parsimine ebaõnnestus', e);
localStorage.removeItem('user');
}
}
setIsLoading(false);
}, []);
return { user, isLoading, login, logout };
}
// AuthProvider komponent rakenduse või selle osade mähkimiseks
export function AuthProvider({ children }) {
const auth = useAuth(); // Siin kasutatakse meie kohandatud hooki
return (
<AuthContext.Provider value={auth}>
{children}
</AuthContext.Provider>
);
}
// Kohandatud Hook AuthContexti tarbimiseks
export function useAuthContext() {
const context = useContext(AuthContext);
if (context === undefined) {
throw new Error('useAuthContext peab olema kasutatud AuthProvideri sees');
}
return context;
}
Kasutusnäide:
// App.js (või juurkomponent)
import React from 'react';
import { AuthProvider, useAuthContext } from './AuthContext';
function Dashboard() {
const { user, isLoading, logout } = useAuthContext();
if (isLoading) return <p>Laen autentimisstaatust...</p>;
if (!user) return <p>Palun logige sisse.</p>;
return (
<div>
<h2>Tere tulemast, {user.name}!</h2>
<button onClick={logout}>Logi välja</button>
</div>
);
}
function LoginFormForContext() {
const { login } = useAuthContext();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleLogin = async (e) => {
e.preventDefault();
const success = await login(username, password);
if (!success) {
alert('Sisselogimine ebaõnnestus!');
}
};
return (
<form onSubmit={handleLogin}>
<input type="text" placeholder="Kasutajanimi" value={username} onChange={e => setUsername(e.target.value)} />
<input type="password" placeholder="Parool" value={password} onChange={e => setPassword(e.target.value)} />
<button type="submit">Logi sisse</button>
</form>
);
}
function App() {
return (
<AuthProvider>
<h1>Autentimise näide kohandatud Hooki ja Contextiga</h1>
<LoginFormForContext />
<Dashboard />
</AuthProvider>
);
}
export default App;
Asünkroonsete Operatsioonide Sujuv Käsitlemine
Asünkroonsete operatsioonide (nagu andmete pärimine) teostamisel kohandatud Hookides on ülioluline käsitleda potentsiaalseid probleeme nagu võidujooksu tingimused (race conditions) või katse uuendada olekut eemaldatud komponendis. AbortController'i või ref-i kasutamine komponendi olemasolu jälgimiseks on levinud strateegiad.
// AbortController'i näide useFetch'is (selguse huvides lihtsustatud)
import React, { useState, useEffect } from 'react';
function useFetchAbortable(url) {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const abortController = new AbortController();
const signal = abortController.signal;
setLoading(true);
setError(null);
fetch(url, { signal })
.then(response => {
if (!response.ok) throw new Error(response.statusText);
return response.json();
})
.then(setData)
.catch(err => {
if (err.name === 'AbortError') {
console.log('Päring katkestati');
} else {
setError(err);
}
})
.finally(() => setLoading(false));
return () => {
// Katkesta päring, kui komponent eemaldatakse või sõltuvused muutuvad
abortController.abort();
};
}, [url]);
return { data, error, loading };
}
export default useFetchAbortable;
Memoiseerimine useCallback'i ja useMemo'ga Hookides
Kuigi kohandatud Hookid ise ei põhjusta jõudlusprobleeme, võivad seda teha nende tagastatavad väärtused ja funktsioonid. Kui kohandatud Hook tagastab funktsioone või objekte, mis luuakse igal renderdamisel uuesti, ja need edastatakse prop'idena memoiseeritud alamkomponentidele (nt komponendid, mis on mähitud React.memo'sse), võib see põhjustada tarbetuid uuesti renderdusi. Kasutage useCallback'i funktsioonide ja useMemo'd objektide/massiivide jaoks, et tagada stabiilsed viited renderduste vahel, täpselt nagu teeksite seda komponendis.
Kohandatud Hookide Testimine
Kohandatud Hookide testimine on nende usaldusväärsuse tagamiseks ülioluline. Teegid nagu @testing-library/react-hooks (nüüd osa @testing-library/react'ist kui renderHook) pakuvad utiliite Hooki loogika testimiseks isoleeritud, komponendist sõltumatul viisil. Keskenduge oma Hooki sisendite ja väljundite ning selle kõrvalmõjude testimisele.
// useCounter'i näitlik test (kontseptuaalne)
import { renderHook, act } from '@testing-library/react-hooks';
import useCounter from './useCounter';
describe('useCounter', () => {
it('peaks loendurit suurendama', () => {
const { result } = renderHook(() => useCounter(0));
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
it('peaks loenduri algväärtusele lähtestama', () => {
const { result } = renderHook(() => useCounter(5));
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(6);
act(() => {
result.current.reset();
});
expect(result.current.count).toBe(5);
});
// Veel teste vähendamise, algväärtuse jms kohta.
});
Dokumentatsioon ja Leitavus
Et kohandatud Hookid oleksid tõeliselt taaskasutatavad, eriti suuremates meeskondades või avatud lähtekoodiga projektides, peavad need olema hästi dokumenteeritud. Kirjeldage selgelt, mida Hook teeb, selle parameetreid ja mida see tagastab. Kasutage selguse huvides JSDoc kommentaare. Kaaluge jagatud Hookide avaldamist npm pakettidena, et tagada lihtne leitavus ja versioonihaldus mitme projekti või mikro-esirakenduse vahel.
Globaalsed Kaalutlused ja Jõudluse Optimeerimine
Globaalsele publikule mõeldud rakenduste ehitamisel võivad kohandatud Hookid mängida olulist rolli rahvusvahelistamise, ligipääsetavuse ja jõudlusega seotud keerukuste abstraheerimisel erinevates keskkondades.
Rahvusvahelistamine (i18n) Hookides
Kohandatud Hookid võivad kapseldada rahvusvahelistamisega seotud loogikat. Näiteks useTranslation hook (mida pakuvad sageli i18n teegid nagu react-i18next) võimaldab komponentidel pääseda juurde tõlgitud stringidele. Samamoodi võiksite ehitada useLocaleDate või useLocalizedCurrency hooki kuupäevade, numbrite või valuuta vormindamiseks vastavalt kasutaja lokaadile, tagades ühtlase kasutajakogemuse kogu maailmas.
// Kontseptuaalne useLocalizedDate hook
import { useState, useEffect } from 'react';
function useLocalizedDate(dateString, locale = 'en-US', options = {}) {
const [formattedDate, setFormattedDate] = useState('');
useEffect(() => {
try {
const date = new Date(dateString);
setFormattedDate(date.toLocaleDateString(locale, options));
} catch (e) {
console.error('Vigane kuupäevastring edastati useLocalizedDate\'ile:', dateString, e);
setFormattedDate('Vigane kuupäev');
}
}, [dateString, locale, JSON.stringify(options)]);
return formattedDate;
}
// Kasutus:
// const myDate = useLocalizedDate('2023-10-26T10:00:00Z', 'de-DE', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
// // myDate oleks 'Donnerstag, 26. Oktober 2023'
Ligipääsetavuse (a11y) Parimad Praktikad
Kohandatud Hookid aitavad jõustada ligipääsetavuse parimaid praktikaid. Näiteks useFocusTrap hook saab tagada, et klaviatuurinavigatsioon jääb modaalakna dialoogi piiresse, või useAnnouncer hook võiks saata teateid ekraanilugejatele dünaamiliste sisuuuenduste kohta, parandades kasutatavust puuetega inimestele kogu maailmas.
Jõudlus: Debouncing ja Throttling
Otsingusoovitustega sisendväljade või kasutaja sisendist käivitatavate raskete arvutuste puhul võib debouncing või throttling märkimisväärselt parandada jõudlust. Need mustrid sobivad ideaalselt kohandatud Hookide jaoks.
useDebounce: Väärtuste Uuendamise Viivitamine
See hook tagastab väärtuse debounce'itud versiooni, mis tähendab, et väärtus uueneb alles pärast teatud viivitust pärast viimast muudatust. Kasulik otsinguribade, sisendi valideerimiste või API-kutsete jaoks, mis ei peaks iga klahvivajutusega käivituma.
import { useState, useEffect } from 'react';
/**
* Kohandatud hook väärtuse debounce'imiseks.
* @param {any} value - Väärtus, mida debounce'ida.
* @param {number} delay - Viivitus millisekundites.
* @returns {any} Debounce'itud väärtus.
*/
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return debouncedValue;
}
export default useDebounce;
Kasutusnäide (Reaalajas Otsing):
import React, { useState } from 'react';
import useDebounce from './useDebounce';
function SearchInput() {
const [searchTerm, setSearchTerm] = useState('');
const debouncedSearchTerm = useDebounce(searchTerm, 500); // 500ms viivitus
// Efekt otsingutulemuste pärimiseks debouncedSearchTerm'i alusel
useEffect(() => {
if (debouncedSearchTerm) {
console.log(`Pärin tulemusi päringule: ${debouncedSearchTerm}`);
// Tee API-kutse siin
} else {
console.log('Otsingutermin tĂĽhjendatud.');
}
}, [debouncedSearchTerm]);
return (
<div>
<input
type="text"
placeholder="Otsi..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<p>Otsin: <strong>{debouncedSearchTerm || '...'}</strong></p>
</div>
);
}
export default SearchInput;
Serveripoolse Renderdamise (SSR) Ăśhilduvus
Arendades kohandatud Hooke SSR-rakendustele (nt Next.js, Remix), pidage meeles, et useEffect ja useLayoutEffect käivituvad ainult kliendi poolel. Kui teie Hook sisaldab loogikat, mis peab käivituma serveri renderdamise faasis (nt esialgne andmete pärimine, mis hüdreerib lehte), peate kasutama alternatiivseid mustreid või tagama, et selline loogika käsitletakse serveris asjakohaselt. Hookid, mis suhtlevad otse brauseri DOM-i või window objektiga, peaksid tavaliselt kaitsma end serveripoolse täitmise eest (nt typeof window !== 'undefined').
Järeldus: Oma Reacti Arendusvoo Võimestamine Globaalselt
Reacti kohandatud Hookid on midagi enamat kui lihtsalt mugavus; need esindavad fundamentaalset nihet selles, kuidas me struktureerime ja taaskasutame loogikat Reacti rakendustes. Meisterdades kohandatud Hookide arendamist, saate võime:
- Kirjutada Korduvkoodivaba Koodi (DRY): Kõrvaldage dubleerimine, tsentraliseerides ühise loogika.
- Parandada Loetavust: Muutke komponendid lĂĽhikeseks ja keskendunuks oma peamistele kasutajaliidese vastutusaladele.
- Tõhustada Testitavust: Isoleerige ja testige keerulist loogikat kergesti.
- Suurendada Hooldatavust: Lihtsustage tulevasi uuendusi ja veaparandusi.
- Soodustada Koostööd: Pakkuge selgeid, hästi määratletud API-sid jagatud funktsionaalsuse jaoks globaalsetes meeskondades.
- Optimeerida Jõudlust: Rakendage tõhusalt mustreid nagu debouncing ja memoiseerimine.
Globaalsele publikule suunatud rakenduste jaoks on kohandatud Hookide struktureeritud ja modulaarne olemus eriti kasulik. Need võimaldavad arendajatel ehitada vastupidavaid, järjepidevaid ja kohandatavaid kasutajakogemusi, mis suudavad toime tulla erinevate keeleliste, kultuuriliste ja tehniliste nõuetega. Olenemata sellest, kas ehitate väikest sisemist tööriista või suuremahulist ettevõtte rakendust, viib kohandatud Hookide mustrite omaksvõtmine kahtlemata tõhusama, nauditavama ja skaleeruvama Reacti arenduskogemuseni.
Alustage täna oma kohandatud Hookidega eksperimenteerimist. Tuvastage oma komponentides korduv loogika, eraldage see ja vaadake, kuidas teie koodibaas muutub puhtamaks, võimsamaks ja globaalselt valmis Reacti rakenduseks.